﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
using System.Web.Http;
using Knlght.Domain;

namespace Knight.Web.Infrastructure
{
    /// <summary>
    /// 上传辅助类
    /// </summary>
    public static class UploadHelper
    {
        public const string DEFAULT_UPLOAD_PATH = "uploads";    //默认上传路径
        public const string TEMP_SIGN = "$temp$";

        public static ItemResponse<string[]> upload(string uploadDirectory, Func<string, bool> validateExt = null, bool isTemp = true)
        {
            var files = System.Web.HttpContext.Current.Request.Files;
            if (files.Count < 1)
            {
                return new ItemResponse<string[]>(false, "没有上传文件");
            }

            uploadDirectory = uploadDirectory.Trim('/');
            if (string.IsNullOrEmpty(uploadDirectory))
            {
                throw new ArgumentNullException("uploadDirectory");
            }
            //添加临时标志
            if (isTemp)     //如果是临时文件，则先上传到临时目录下面
            {
                uploadDirectory += TEMP_SIGN;
            }
            var result = new List<String>();
            var today = DateTime.Now.ToString("yyyy-MM-dd");
            var fullDic = System.Web.Hosting.HostingEnvironment.MapPath(string.Format("~/{0}/{1}/{2}/", DEFAULT_UPLOAD_PATH, uploadDirectory, today));
            if (!System.IO.Directory.Exists(fullDic))
            {
                System.IO.Directory.CreateDirectory(fullDic);
            }

            if (validateExt != null)        //扩展名验证
            {
                for (var i = 0; i < files.Count; i++)
                {
                    var file = files[i];
                    var ext = System.IO.Path.GetExtension(file.FileName);
                    if (!validateExt(ext))
                    {
                        return new ItemResponse<string[]>(false, string.Format("文件{0}不是允许上传的类型!", file.FileName));
                    }
                }
            }


            for (var i = 0; i < files.Count; i++)
            {
                var file = files[i];

                if (file.ContentLength < 1)
                {
                    continue;
                }

                var fileName = Guid.NewGuid().ToString();
                var ext = System.IO.Path.GetExtension(file.FileName);

                var path = fullDic + fileName + ext;
                file.SaveAs(path);

                result.Add(string.Format("/{0}/{1}/{2}/{3}{4}", DEFAULT_UPLOAD_PATH, uploadDirectory, today, fileName, ext));
            }

            if (result.Count == 0)
            {
                return new ItemResponse<string[]>(false, "上传文件的大小不能为0");
            }
            else
            {
                return new ItemResponse<string[]>(true) { Model = result.ToArray() };
            }
        }
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="controller"></param>
        /// <param name="uploadDirectory">上传目录</param>
        /// <returns></returns>
        public static ItemResponse<string[]> Upload(this Controller controller, string uploadDirectory, Func<string, bool> validateExt = null)
        {
            return upload(uploadDirectory, validateExt);
        }
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="controller"></param>
        /// <param name="uploadDirectory">上传目录</param>
        /// <returns></returns>
        public static ItemResponse<string> Upload(this ApiController controller, string uploadDirectory, Func<string, bool> validateExt = null)
        {
            //直接上传到正式目录下面
            var rsp = upload(uploadDirectory, validateExt, false);

            string model = "";
            if (rsp.IsSuccess)
            {
                if (rsp.Model.Length > 0)
                {
                    model = rsp.Model[0];
                }
            }

            return new ItemResponse<string>()
            {
                IsSuccess = rsp.IsSuccess,
                ResultCode = rsp.ResultCode,
                Message = rsp.Message,
                Model = model
            };
        }
        /// <summary>
        /// 上传图片
        /// </summary>
        public static ItemResponse<string[]> UploadPics(this Controller controller, string uploadDirectory)
        {
            return Upload(controller, uploadDirectory, (ext) =>
            {
                var extName = ext.ToLower();
                return extName == ".jpeg" || extName == ".jpg" || extName == ".png" || extName == ".gif" || extName == ".bmp";
            });
        }
        /// <summary>
        /// 上传图片
        /// </summary>
        public static ItemResponse<string> UpdatePics(this ApiController controller, string uploadDirectory)
        {
            return Upload(controller, uploadDirectory, (ext) =>
            {
                var extName = ext.ToLower();
                return extName == ".jpeg" || extName == ".jpg" || extName == ".png" || extName == ".gif" || extName == ".bmp";
            });
        }
        /// <summary>
        /// 将临时文件移动到正式路径下
        /// </summary>
        /// <param name="tempPath">临时文件路径</param>
        /// <param name="targetPath">目录文件路径(为空时，表示使用去除临时文件路径标志的对应路径</param>
        public static string MoveFile(string tempPath, string targetPath = "")
        {
            if (string.IsNullOrEmpty(tempPath))
            {
                return "";
            }

            //如果临时文件夹不存在图片，即表示之前已经移动过，直接将地址去掉临时标记即可
            if (!System.IO.File.Exists(System.Web.HttpContext.Current.Server.MapPath(tempPath)))
            {
                tempPath = tempPath.Replace(TEMP_SIGN, "");
            }

            //判断临时标志是否存在
            if (tempPath.IndexOf(TEMP_SIGN) < 0)
            {
                return string.IsNullOrEmpty(targetPath) ? tempPath : targetPath;
            }
            string fullTempPath = System.Web.Hosting.HostingEnvironment.MapPath("~" + tempPath);
            if (!System.IO.File.Exists(fullTempPath))
            {
                throw new ApplicationException("临时文件" + fullTempPath + "不存在!");
            }

            string targetFullPath = "";
            if (!string.IsNullOrEmpty(targetPath))
            {
                if (targetPath.StartsWith("/"))
                {
                    targetFullPath = System.Web.HttpContext.Current.Server.MapPath("~" + targetPath);
                    //targetFullPath = System.Web.Hosting.HostingEnvironment.MapPath("~" + targetPath);
                }
                else
                {
                    targetFullPath = System.Web.HttpContext.Current.Server.MapPath("~/" + targetPath);
                    //targetFullPath = System.Web.Hosting.HostingEnvironment.MapPath("~/" + targetPath);
                }
            }
            else
            {
                targetFullPath = fullTempPath.Replace(TEMP_SIGN, "");
            }

            System.Threading.Tasks.Task.Factory.StartNew(() =>
            {
                if (System.IO.File.Exists(targetFullPath))
                {
                    System.IO.File.Delete(targetFullPath);
                }

                //判断目标文件侠是否存在
                var dir = System.IO.Path.GetDirectoryName(targetFullPath);
                if (!System.IO.Directory.Exists(dir))
                {
                    System.IO.Directory.CreateDirectory(dir);
                }

                //该操作需要删除文件，所以需要修改权限
                System.IO.File.Move(fullTempPath, targetFullPath);
            });

            return string.IsNullOrEmpty(targetPath) ? tempPath.Replace(TEMP_SIGN, "") : targetPath;
        }

        /// <summary>
        /// 删除指定的文件
        /// </summary>
        public static void DeleteFile(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                return;
            }

            if (path.ToLower().StartsWith("http://"))
            {
                return;
            }
            else
            {
                try
                {
                    string fullPath = System.Web.Hosting.HostingEnvironment.MapPath("~" + path);

                    Task.Factory.StartNew(() =>
                    {
                        if (System.IO.File.Exists(fullPath))
                        {
                            System.IO.File.Delete(fullPath);
                        }
                    });
                }
                catch
                {

                }

            }
        }
    }
}
